using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using slcl;
using SimpleMessageQueue;

namespace slcl.TestClient.GUI
{
    public partial class MainDisplay : Form
    {

        // FIXME wrapper with get methods for protection.

        public MessageQueue MQueue;
        public Client client;

        LogDisplay LogDisplay;
        System.Threading.Thread LogThread;
        System.Threading.Thread LoginThread;
        AcountSettings LoginDisplay;
        public MainDisplay()
        {
            // create our log display.
            LogDisplay = new LogDisplay();
            LogThread = new System.Threading.Thread(LogDisplay.Run);
            LogThread.Start();
            LoginDisplay = new AcountSettings(this);
            LoginThread = new System.Threading.Thread(LoginDisplay.Run);
            LoginThread.Start();

            // draw our main display
            InitializeComponent();

            //create and request thread creation for our message queue.
            // this is how we will talk to slcl for events.
            MQueue = new MessageQueue(this, true);

            // tell mqueue where to send Info type packets.
            MQueue.RegisterPacketCallback(SimpleMessageQueue.Message.MessageType.Info
                                          , new MessageQueue.MessageCallback(HandleInfoMessage));

            // Create the client.
            client = new Client();

            // ask Client to send us anything of log event. The following four show handling 
            // of different levels of log acks.

//            MQueue.Send(new RegisteredMessage(new object[] { Client.Events.Log, Helpers.LogLevel.Info }
//                , new CommandMessage.AckCallback(HandleInfoAck)), client);
//            MQueue.Send(new RegisteredMessage(new object[] { Client.Events.Log, Helpers.LogLevel.Debug }
//                , new CommandMessage.AckCallback(HandleInfoAck)), client);
//            MQueue.Send(new RegisteredMessage(new object[] { Client.Events.Log, Helpers.LogLevel.Warning }
//                , new CommandMessage.AckCallback(HandleInfoAck)), client);
//            MQueue.Send(new RegisteredMessage(new object[] { Client.Events.Log, Helpers.LogLevel.Error }
//                , new CommandMessage.AckCallback(HandleInfoAck)), client);

            // log all messages of type AckMessage concerning event Log
            MQueue.Send(new RegisteredMessage(new object[] { Client.Events.Log}
                , new CommandMessage.AckCallback(HandleInfoAck)), client);

            // so we can clean up our children should we be prematurely destroyed (or X clicked)
            Disposed += new EventHandler(Form1_Disposed);
            // an empty client. We'll provide the login and whatnot at login time.
        }

        void Form1_Disposed(object sender, EventArgs e)
        {
            MQueue.Send(new CommandMessage(Client.Commands.Shutdown), client);
            MQueue.Shutdown = true;
            LogThread.Abort();
            LoginThread.Abort();
        }

 

        private void loginButton_Click(object sender, EventArgs e)
        {
        }

        public void LoginHandler(SimpleMessageQueue.Message msg)
        {
            PostLogEntry("Login returned.");
        }

        #region Logging
        public void HandleInfoMessage(SimpleMessageQueue.Message msg)
        {
            // convert the message to the info type.
            InfoMessage Msg = (InfoMessage)msg;

            // make certain that we have data.
            if (null != Msg.Args && Msg.Args.Length >= 1)
            {
                PostLogEntry((string)Msg.Args[0], (Msg.Args.Length == 2 ? (Helpers.LogLevel)Msg.Args[1] : Helpers.LogLevel.Info));
            }
        }

        public void HandleInfoAck(SimpleMessageQueue.Message msg)
        {
            AckMessage Msg = (AckMessage)msg;
            PostLogEntry((string)Msg.Args[0], (Helpers.LogLevel)Msg.Args[1]);
        }

        void PostLogEntry(string msg, Helpers.LogLevel lvl)
        {
            if (LogDisplay != null)
            {
                LogDisplay.PostLogEntry(msg, lvl);
            }
        }

        void PostLogEntry(string msg)
        {
            PostLogEntry(msg, Helpers.LogLevel.Info);
        }

        #endregion

        private void logoutButton_Click(object sender, EventArgs e)
        {
            MQueue.Send(new CommandMessage(Client.Commands.Logout, null, new CommandMessage.AckCallback(LogoutHandler)), client);            
        }

        public void LogoutHandler(SimpleMessageQueue.Message msg)
        {
            PostLogEntry("Logout returned.");
        }

        private void clientLoginButton_Click(object sender, EventArgs e)
        {
            if (null == LoginThread)
            {
                if (null == LoginDisplay)
                    LoginDisplay = new AcountSettings(this);
                LoginThread = new System.Threading.Thread(LoginDisplay.Run());
                LoginThread.Start();
            }
        }
    }
}